/*
 *   Copyright 2021 zzh
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */

package com.aduib.boot.common.zookeeper;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

/**
 * @description: CuratorBase
 * @author: zzh
 * @date: 2022/1/26 14:57
 */
public class CuratorBase {
  // 会话超时时间
  private static final int SESSION_TIMEOUT = 30 * 1000;

  // 连接超时时间
  private static final int CONNECTION_TIMEOUT = 3 * 1000;

  // ZooKeeper服务地址
  private static final String CONNECT_ADDR = "192.168.1.1:2100,192.168.1.1:2101,192.168.1.:2102";

  // 创建连接实例
  private CuratorFramework client = null;

  public static void main(String[] args) throws Exception {
    // 1 重试策略：初试时间为1s 重试10次
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);
    // 2 通过工厂创建连接
    CuratorFramework client =
        CuratorFrameworkFactory.builder()
            .connectString(CONNECT_ADDR)
            .connectionTimeoutMs(CONNECTION_TIMEOUT)
            .sessionTimeoutMs(SESSION_TIMEOUT)
            .retryPolicy(retryPolicy)
            // 命名空间           .namespace("super")
            .build();
    // 3 开启连接
    client.start();

    System.out.println(ZooKeeper.States.CONNECTED);
    System.out.println(client.getState());

    // 创建永久节点
    client.create().forPath("/curator", "/curator data".getBytes());

    // 创建永久有序节点
    client
        .create()
        .withMode(CreateMode.PERSISTENT_SEQUENTIAL)
        .forPath("/curator_sequential", "/curator_sequential data".getBytes());

    // 创建临时节点
    client
        .create()
        .withMode(CreateMode.EPHEMERAL)
        .forPath("/curator/ephemeral", "/curator/ephemeral data".getBytes());

    // 创建临时有序节点
    client
        .create()
        .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
        .forPath("/curator/ephemeral_path1", "/curator/ephemeral_path1 data".getBytes());

    client
        .create()
        .withProtection()
        .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
        .forPath("/curator/ephemeral_path2", "/curator/ephemeral_path2 data".getBytes());

    // 测试检查某个节点是否存在
    Stat stat1 = client.checkExists().forPath("/curator");
    Stat stat2 = client.checkExists().forPath("/curator2");

    System.out.println("'/curator'是否存在： " + (stat1 != null ? true : false));
    System.out.println("'/curator2'是否存在： " + (stat2 != null ? true : false));

    // 获取某个节点的所有子节点
    System.out.println(client.getChildren().forPath("/"));

    // 获取某个节点数据
    System.out.println(new String(client.getData().forPath("/curator")));

    // 设置某个节点数据
    client.setData().forPath("/curator", "/curator modified data".getBytes());

    // 创建测试节点
    client
        .create()
        .orSetData()
        .creatingParentContainersIfNeeded()
        .forPath("/curator/del_key1", "/curator/del_key1 data".getBytes());

    client
        .create()
        .orSetData()
        .creatingParentContainersIfNeeded()
        .forPath("/curator/del_key2", "/curator/del_key2 data".getBytes());

    client.create().forPath("/curator/del_key2/test_key", "test_key data".getBytes());

    // 删除该节点
    client.delete().forPath("/curator/del_key1");

    // 级联删除子节点
    client.delete().guaranteed().deletingChildrenIfNeeded().forPath("/curator/del_key2");
  }
}
